﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Web.Script.Serialization;

namespace RedditViewer
{
    public class jsonLogin
    {
        public jsonLoginResult json { get; set; }
    }
    public class jsonLoginResult
    {
        public jsonLoginResultData data { get; set; }
        public List<List<string>> errors { get; set; }
    }
    public class jsonLoginResultData
    {
        public string modhash { get; set; }
        public string cookie { get; set; }
    }



    public class jsonSubreddit
    {
        public string display_name { get; set; }
        public string description { get; set; }
        public string name { get; set; }
        public double created { get; set; }
        public string url { get; set; }
        public string title { get; set; }
        public double created_utc { get; set; }
        public string public_description { get; set; }
        public List<int?> header_size { get; set; }
        public bool over18 { get; set; }
        public int accounts_active { get; set; }
        public int subscribers { get; set; }
        public string header_title { get; set; }
        public string id { get; set; }
        public string header_img { get; set; }
    }

    public class jsonSubredditsChild
    {
        public string kind { get; set; }
        public jsonSubreddit data { get; set; }
    }

    public class jsonSubredditsData
    {
        public string modhash { get; set; }
        public List<jsonSubredditsChild> children { get; set; }
        public object after { get; set; }
        public object before { get; set; }
    }

    public class jsonSubredditsResult
    {
        public string kind { get; set; }
        public jsonSubredditsData data { get; set; }
    }

    public class LoginFailedException : Exception
    {
        public LoginFailedException(string Reason) : base(Reason)        {        }
    }


    public class ApiHelper
    {
        private static jsonLoginResultData session;

        private static WebClient GetWebClient()
        {
            WebClient wc = new WebClient();
            wc.Headers[HttpRequestHeader.UserAgent] = "RedditViewer/" + (Properties.Settings.Default.Username ?? "UnknownUser");

            if (LoggedIn)
            {
                wc.Headers[HttpRequestHeader.Cookie] = "reddit_session=" + Uri.EscapeDataString(session.cookie);
            }

            return wc;
        }

        public static bool LoggedIn
        {
            get
            {
                return session != null;
            }
        }

        public static bool Login(string Username, string Password, out string error)
        {
            error = null;

            string URI = "https://ssl.reddit.com/api/login/" + Username;
            string myParameters = "user=" + Uri.EscapeDataString(Username)
                + "&passwd=" + Uri.EscapeDataString(Password)
                + "&api_type=json";

            using (WebClient wc = GetWebClient())
            {
                wc.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded";
                string HtmlResult = wc.UploadString(URI, myParameters);
                JavaScriptSerializer ser = new JavaScriptSerializer();
                jsonLogin result = ser.Deserialize<jsonLogin>(HtmlResult);


                if (result.json.errors != null && result.json.errors.Count > 0)
                {
                    error = result.json.errors[0][0];
                    return false;
                }

                session = result.json.data;
                return true;
            }
        }

        public static void Login()
        {
            Login(Properties.Settings.Default.Username, Properties.Settings.Default.Password);
        }
        public static void Login(string Username, string Password)
        {
            string error;
            if (!Login(Username, Password, out error))
                throw new LoginFailedException(error);
            
        }

        private static string Get(string url)
        {
            using (WebClient wc = GetWebClient())
            {
                return wc.DownloadString(url);
            }
        }

        private static T Get<T>(string url)
        {
            string s = Get(url);
            JavaScriptSerializer ser = new JavaScriptSerializer();
            return ser.Deserialize<T>(s);
        }

        private static List<jsonSubreddit> mySubreddits = null;
        public static List<jsonSubreddit> GetMySubreddits()
        {
            if (mySubreddits == null)
            {
                if (!LoggedIn)
                    Login();
                mySubreddits = Get<jsonSubredditsResult>("http://www.reddit.com/reddits/mine/.json").data.children.Select(_ => _.data).ToList();
            }
            return mySubreddits;
        }
    }
}
